package com.etop.weiway.wxmanage.service;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.etop.weiway.basic.service.BaseService;
import com.etop.weiway.commons.web.Pager;
import com.etop.weiway.wxmanage.dao.*;
import com.etop.weiway.wxmanage.entity.*;
import com.etop.weiway.wxmanage.util.WeixinTimeUtil;
import com.etop.weixin.entity.advanced.Article;
import com.etop.weixin.entity.advanced.WxGroupParam;
import com.etop.weixin.entity.advanced.WxGroups;
import com.etop.weixin.entity.advanced.WxNews;
import com.etop.weixin.utils.MassMsgUtil;
import com.etop.weixin.utils.WxGroupUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author Jessy
 */
@Service("MassMsgService")
public class MassMessageService extends BaseService {

    @Autowired
    private MassDAO massDAO;
    @Autowired
    private MaterialService materialService;
    @Autowired
    private AccountDAO accountDAO;
    @Autowired
    private WeixinUserDAO weixinUserDAO;
    @Autowired
    private WeixinUserGroupDAO weixinUserGroupDAO;
    @Autowired
    private MaterialMutinewsDAO materialMutinewsDAO;
    @Autowired
    private MaterialImageDAO materialImageDAO;
    @Autowired
    private MaterialTextDAO materialTextDAO;
    @Autowired
    private MaterialVideoDAO materialVideoDAO;
    @Autowired
    private MaterialVoiceDAO materialVoiceDAO;
    @Autowired
    private MaterialNewsDAO materialNewsDAO;
    /**
     * 根据局id获取mass对象
     * @param id
     * @return 
     */
    public Mass loadMass(Integer id) {
        log.debug("*******根据id获取mass对象*********");
        Mass mass = massDAO.get(id);
        return mass;
    }

    /**
     * 根据OpenIds 群发文本消息
     *
     * @param accessToken
     * @param openIds
     * @param content
     * @return
     */
    public long sendTextMsgByOpenIds(String accessToken, ArrayList<String> openIds, String content) {
        log.debug("*******根据OpenIds发送文本信息********");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createTextMsg(openIds, content);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, false);
        return msgId;
    }

    /**
     * 根据GroupId 群发文本消息
     *
     * @param accessToken
     * @param groupId
     * @param content
     * @return
     */
    public long sendTextMsgByGroup(String accessToken, String groupId, String content) {
        log.debug("*******根据组ID发送文本信息********");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createTextMsg(groupId, content);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, true);
        return msgId;
    }

    /**
     * 根据OpenIds 群发图文消息
     *
     * @param accessToken
     * @param openIds
     * @param mediaId
     * @return
     */
    public long sendNewsMsgByOpenIds(String accessToken, ArrayList<String> openIds, String mediaId) {
        log.debug("*******根据OpenIds发送图文信息********");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createNewsMsg(openIds, mediaId);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, false);
        return msgId;
    }

    /**
     * 根据GroupId群发图文消息
     *
     * @param accessToken
     * @param groupId
     * @param content
     * @return
     */
    public long sendNewsMsgByGroup(String accessToken, String groupId, String content) {
        log.debug("*******根据组id发送图文文本信息********");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createNewsMsg(groupId, content);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, true);
        return msgId;
    }

    /**
     * 根据OpenIds 群发图片消息
     *
     * @param accessToken
     * @param openIds
     * @param mediaId
     * @return
     */
    public long sendImageMsgByOpenIds(String accessToken, ArrayList<String> openIds, String mediaId) {
        log.debug("*******根据OpenIds发送图片信息********");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createImageMsg(openIds, mediaId);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, false);
        return msgId;
    }

    /**
     * 根据Group 群发图片消息
     *
     * @param accessToken
     * @param groupId
     * @param content
     * @return
     */
    public long sendImageMsgByGroup(String accessToken, String groupId, String content) {
        log.debug("*******根据组id发送图片信息********");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createImageMsg(groupId, content);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, true);
        return msgId;
    }

    /**
     * 根据openIds群发视频消息
     *
     * @param accessToken
     * @param openIds
     * @param materialVideo
     * @return
     */
    public long sendVideoMsgByOpenIds(String accessToken, ArrayList<String> openIds, MaterialVideo materialVideo,String mediaId) {
        log.debug("******根据openIds群发视频消息******");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createVideoMsg(openIds,mediaId, materialVideo.getTitle(), materialVideo.getDescription());
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, false);
        return msgId;
    }

    /**
     * 根据groupId群发视频消息
     *
     * @param accessToken
     * @param groupId
     * @param mediaId
     * @return
     */
    public long sendVideoMsgByGroup(String accessToken, String groupId, String mediaId) {
        log.debug("******根据groupId群发视频消息******");
        System.out.println("gropu id is " + groupId);
        String jsonMsg = com.etop.weixin.service.MassMsgService.createVideoMsg(groupId, mediaId);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, true);
        return msgId;
    }

    /**
     * 根据openIds群发音频消息
     *
     * @param accessToken
     * @param openIds
     * @param mediaId
     * @return
     */
    public long sendVoiceMsgByOpenIds(String accessToken, ArrayList<String> openIds, String mediaId) {
        log.debug("******根据openIds群发音频消息******");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createVoiceMsg(openIds, mediaId);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, false);
        return msgId;
    }

    /**
     * 根据groupId群发音频消息
     *
     * @param accessToken
     * @param groupId
     * @param mediaId
     * @return
     */
    public long sendVoiceMsgByGroup(String accessToken, String groupId, String mediaId) {
        log.debug("******根据groupId群发音频消息******");
        String jsonMsg = com.etop.weixin.service.MassMsgService.createVoiceMsg(groupId, mediaId);
        long msgId = MassMsgUtil.sendMassMsg(accessToken, jsonMsg, true);
        return msgId;
    }

//    public ArrayList<WxGroupParam> getGroupsByCurrentAccount(String accessToken){
//        WxGroups wxGroups = WxGroupUtil.getAllGroups(accessToken);
//        ArrayList<WxGroupParam> groups = wxGroups.getGroups();
//        return groups;
//    }
    /**
     * 根据当前公众号id获得公众号所有分组
     *
     * @param accountId
     * @return
     * @throws java.lang.Exception
     */
//    public String getWxGroupListById(int accountId) throws Exception {
//        log.debug("*******根据当前公众号id获得公众号所有分组********");
//        Map<String, Object> params = this.createParamMap();
//        params.put("id", accountId);
//        Account account = accountDAO.findUniqueResult("from Account t where t.valid = 1 and t.id = :id", params);
//        String accessToken = null;
//        try {
//            accessToken = WeixinTimeUtil.getAccessToken(account);
//        }catch (Exception e){
//            return "获取accessToken失败，请检查你的公众号设置是否有问题。";
//        }
//        WxGroups allGroups = null;
//        try {
//         allGroups = WxGroupUtil.getAllGroups(accessToken);
//        }catch (Exception e){
//            return "获取分组失败。";
//        }
//        return JSONObject.toJSONString(allGroups);
//    }

    /**
     * 根据当前公众号获取所有本地分组
     *
     * @param accountId
     * @return
     * @throws Exception
     */
    public String getGroupListByAccountId(Integer accountId) throws Exception {
        log.debug("**********************根据当前公众号获取所有本地分组**************************");
        Map<String, Object> params = createParamMap();
        params.put("accountId", accountId);
        ArrayList<WxGroupParam> groupParams = new ArrayList<>();
        
        WxGroupParam groupPa = new WxGroupParam();
        groupPa.setId(String.valueOf(0));
        groupPa.setName("未分组");
        groupPa.setCount(String.valueOf(0));
        groupParams.add(groupPa);
        
        String strQuery = "from WeixinUserGroup t where t.account.id = :accountId and t.valid = 1";
        List<WeixinUserGroup> groupList =  weixinUserGroupDAO.find(strQuery, params);
        for (WeixinUserGroup weixinUserGroup : groupList) {
            WxGroupParam groupParam = new WxGroupParam();
            groupParam.setId(String.valueOf(weixinUserGroup.getId()));
            groupParam.setName(weixinUserGroup.getName());
            groupParam.setCount(String.valueOf(weixinUserGroup.getWeixinUsers().size()));
            groupParams.add(groupParam);
        }
        WxGroupParam groupPar = new WxGroupParam();
        groupPar.setId(String.valueOf(-1));
        groupPar.setName("所有人");
        groupPar.setCount(String.valueOf(0));
        groupParams.add(groupPar);
        
        WxGroups allGroups = new WxGroups();
        allGroups.setGroups(groupParams);
        return JSONObject.toJSONString(allGroups);
    }

    /**
     * 获取并设置mass的openIds 要求mass中已经设置account和groupId
     * @param mass
     * @return 
     */
    public ArrayList<String> getOpenIds(Mass mass)
    {
        if(mass.getGroupId()==null||mass.getAccount().getId()==null) 
            return null;
        List<WeixinUser> weixinUsers = null;
        if(mass.getGroupId()==0){
            String queryString = "from WeixinUser t where t.valid = 1 and t.group = null and t.account.id = " + mass.getAccount().getId();
            weixinUsers = weixinUserDAO.find(queryString);
        }
        else if(mass.getGroupId() ==-1){
            String queryString = "from WeixinUser t where t.valid = 1 and t.account.id = " + mass.getAccount().getId();
            weixinUsers = weixinUserDAO.find(queryString);
        }
        else{
            WeixinUserGroup weixinUserGroup = weixinUserGroupDAO.get(mass.getGroupId());
            weixinUsers = weixinUserGroup.getWeixinUsers();
        }
        ArrayList<String> openIds = new ArrayList<>();
        for (WeixinUser weixinUser : weixinUsers) {
            openIds.add(weixinUser.getOpenId());
        }
        mass.setOpenIds(JSON.toJSONString(openIds));
        return openIds;
    }
    
    /**
     * 保存群发消息
     *
     * @param mass
     */
    public void saveMassmsg(Mass mass) {
        log.debug("*******保存群发消息********");
        massDAO.saveOrUpdate(mass);
    }

    /**
     * 分页获取群发消息
     *
     * @param pager
     * @param accountId
     * @return
     * @throws Exception
     */
    public Pager<Mass> getMassByPager(Pager<Mass> pager, int accountId) throws Exception {
        log.debug("******根据条件查询图文素材******");
        String queryString = "from Mass t where t.valid = 1 and t.account.id = " + accountId;
        queryString += " order by t.id desc";
        List<Mass> mass = massDAO.find(queryString, (pager.getPageNo() - 1) * pager.getPageSize(), pager.getPageSize());
        pager.setCount(massDAO.getTotalCount(queryString));
        pager.setList(mass);
        return pager;
    }



    /**
     * 删除群发消息
     *
     * @param id
     */
    public void deleteMassById(int id) {

        log.debug("******根据id删除群发消息******");
        Mass mass = massDAO.get(id);
        massDAO.invalid(mass);
    }

    /**
     * 封装多图文上传时转换为WxNews对象时的处理
     * @param materialMutinews
     * @param basePath
     * @return
     * @throws Exception 
     */
    public WxNews handleMultiNews(MaterialMutinews materialMutinews,String basePath) throws Exception{
        log.debug("******封装多图文上传时转换为WxNews对象时的处理******");
        String multIds = materialMutinews.getMultIds();
                List<MaterialNews> materialNewses = materialService.getMaterialNewsByMultIds(multIds);
                ArrayList<Article> articles = new ArrayList<>();
                WxNews wxNews = new WxNews();
                for (MaterialNews materialNews : materialNewses) {
                    Article article = new Article();
                    if (materialNews.getAuthor() != null) {
                        article.setAuthor(materialNews.getAuthor());
                    }
                    article.setContent(materialNews.getContent());
                    article.setContent_source_url(materialNews.getContentUrl());
                    article.setDigest(materialNews.getDescription());
                    article.setShow_cover_pic(materialNews.getShowCoverPic().toString());
                    String thumbMediaId = WeixinTimeUtil.getThumbImageMediaId(basePath + materialNews.getThumbMedia().getUrl(), materialNews.getThumbMedia());
                    article.setThumb_media_id(thumbMediaId);
                    article.setThumb_media_id(materialNews.getThumbMedia().getMediaId());
                    article.setTitle(materialNews.getTitle());
                    articles.add(article);
                }
                wxNews.setArticles(articles);
                return wxNews;
    }
   /**
     * 上传和群发消息
     *
     * @param mass
     * @param currentAccountId
     * @param basePath
     * @return
     * @throws Exception
     */
    public String handleSendMassMsg(Mass mass, int currentAccountId, String basePath) throws Exception {
        Account account = accountDAO.get(currentAccountId);
        if (mass.getMaterialId() == null) {
            mass.setMaterialType("text");

        }
        //用于区分临时文本还是文本素材
        mass.setAccount(account);
        String result = "";
        ArrayList<String> openIds = getOpenIds(mass);
        if(openIds.isEmpty())
            return "error:所选分组为空";
        long textMsgId = 0;
        switch (mass.getMaterialType()) {
            case "text":
                log.debug("******群发文本消息******");
//修改群发文本的逻辑，因为原先的处理方式可能导致这样的后果：选择文本素材后又在文本框中修改了原先素材的内容，这样群发的文本内容会是没有修改过的素材。
//改成直接根据mass.content，同时如果有选择素材则判断素材是否被修改，没有被修改mass设置素材名称有被修改清除素材id。
                MaterialText materialText = null;
                if (mass.getMaterialId() != null) {
                    String textQuery = "from MaterialText t where t.valid = 1 and t.id = :id";
                    Map<String, Object> textParams = this.createParamMap();
                    textParams.put("id", mass.getMaterialId());
                    materialText = materialTextDAO.findUniqueResult(textQuery, textParams);
                    if(materialText.getContent().equals(mass.getContent())){
                        mass.setMaterialName(materialText.getName());                        
                    }
                    else{
                        mass.setMaterialId(null);
                    }
                }
//                textMsgId = sendTextMsgByOpenIds(WeixinTimeUtil.getAccessToken(mass.getAccount()), getOpenIdsByGroupId(mass.getGroupId(), mass.getAccount().getId()), mass.getContent());
                textMsgId = sendTextMsgByOpenIds(WeixinTimeUtil.getAccessToken(mass.getAccount()),openIds, mass.getContent());
                if (textMsgId != 0) {
                    mass.setMsgId(textMsgId);
                    mass.setStatus("群发消息正在发送中......");
                    massDAO.save(mass);
                    result = "群发消息成功";
                } else {
                    return "error:群发消息失败";
                }
                break;
            case "image":
                log.debug("******上传和群发图片消息******");
                basePath += "image/";
                String imageQuery = "from MaterialImage t where t.valid = 1 and t.id = :id";
                Map<String, Object> imageParams = this.createParamMap();
                imageParams.put("id", mass.getMaterialId());
                MaterialImage materialImage = materialImageDAO.findUniqueResult(imageQuery, imageParams);
                String mediaId = WeixinTimeUtil.getImageMediaId(basePath + materialImage.getUrl(), materialImage);
                String accessToken = WeixinTimeUtil.getAccessToken(materialImage.getAccount());
                long imageMsgId = sendImageMsgByOpenIds(accessToken, openIds,mediaId);
                if (imageMsgId != 0) {
                    mass.setMaterialName(materialImage.getName());
                    mass.setMsgId(imageMsgId);
                    mass.setStatus("群发消息正在发送中......");
                    massDAO.save(mass);
                    result = "群发消息成功";
                } else {
                    return "error:群发消息失败";
                }
                break;
            case "news":
                log.debug("******上传和群发单图文消息******");
                basePath += "image/";
                String newsQuery = "from MaterialNews t where t.valid = 1 and t.id = :id";
                Map<String, Object> newsParams = this.createParamMap();
                newsParams.put("id", mass.getMaterialId());
                MaterialNews materialNews = materialNewsDAO.findUniqueResult(newsQuery, newsParams);
                MaterialMutinews multiNews = new MaterialMutinews();
                multiNews.setMultIds(materialNews.getId().toString());
                multiNews.setAccount(materialNews.getAccount());
                multiNews.setName(materialNews.getName());
                multiNews.setCreatedTime((long)0);
                materialMutinewsDAO.save(multiNews);
                WxNews news_wxNews = handleMultiNews(multiNews,basePath);
                String newsMediaId = WeixinTimeUtil.getNewsMediaId(multiNews, news_wxNews);
                long newsMsgId = sendNewsMsgByOpenIds(WeixinTimeUtil.getAccessToken(multiNews.getAccount()), openIds, newsMediaId);
                if (newsMsgId != 0) {
                    mass.setMaterialName(multiNews.getName());
                    mass.setMsgId(newsMsgId);
                    mass.setStatus("群发消息正在发送中......");
                    massDAO.save(mass);
                    result = "群发消息成功";
                } else {
                    return "error:群发消息失败";
                }
                break;
            case "mutinews":
                log.debug("******上传和群发多图文消息******");
                basePath += "image/";
                String mutinewsQuery = "from MaterialMutinews t where t.valid = 1 and t.id = :id";
                Map<String, Object> mutinewsParams = this.createParamMap();
                mutinewsParams.put("id", mass.getMaterialId());
                MaterialMutinews materialMutinews = materialMutinewsDAO.findUniqueResult(mutinewsQuery, mutinewsParams);
                WxNews mutinews_wxNews = handleMultiNews(materialMutinews,basePath);
                String mutinewsMediaId = WeixinTimeUtil.getNewsMediaId(materialMutinews, mutinews_wxNews);
                long mutinewsMsgId = sendNewsMsgByOpenIds(WeixinTimeUtil.getAccessToken(materialMutinews.getAccount()), openIds, mutinewsMediaId);
                if (mutinewsMsgId != 0) {
                    mass.setMaterialName(materialMutinews.getName());
                    mass.setMsgId(mutinewsMsgId);
                    mass.setStatus("群发消息正在发送中......");
                    massDAO.save(mass);
                    result = "群发消息成功";
                } else {
                    return "error:群发消息失败";
                }
                break;
            case "video":
                log.debug("******上传和群发视频消息******");
                basePath += "video/";
                String videoQuery = "from MaterialVideo t where t.valid = 1 and t.id = :id";
                Map<String, Object> videoParams = this.createParamMap();
                videoParams.put("id", mass.getMaterialId());
                MaterialVideo materialVideo = materialVideoDAO.findUniqueResult(videoQuery, videoParams);
                String videoMediaId = WeixinTimeUtil.getVideoMassMediaId(basePath + materialVideo.getUrl(), materialVideo);
                long videoMsgId = sendVideoMsgByOpenIds(WeixinTimeUtil.getAccessToken(materialVideo.getAccount()), openIds, materialVideo,videoMediaId);
                if (videoMsgId != 0) {
                    mass.setMaterialName(materialVideo.getName());
                    mass.setMsgId(videoMsgId);
                    mass.setStatus("群发消息正在发送中......");
                    massDAO.save(mass);
                    result = "群发消息成功";
                } else {
                    return "error:群发消息失败";
                }
                break;
            case "voice":
                log.debug("******上传和群发音频消息******");
                basePath += "voice/";
                String voiceQuery = "from MaterialVoice t where t.valid = 1 and t.id = :id";
                Map<String, Object> voiceParams = this.createParamMap();
                voiceParams.put("id", mass.getMaterialId());
                MaterialVoice materialVoice = materialVoiceDAO.findUniqueResult(voiceQuery, voiceParams);
                String voiceMediaId = WeixinTimeUtil.getVoiceMediaId(basePath + materialVoice.getUrl(), materialVoice);
                long voiceMsgId = sendVoiceMsgByOpenIds(WeixinTimeUtil.getAccessToken(materialVoice.getAccount()), openIds, voiceMediaId);
                if (voiceMsgId != 0) {
                    mass.setMaterialName(materialVoice.getName());
                    mass.setMsgId(voiceMsgId);
                    mass.setStatus("群发消息正在发送中......");
                    massDAO.save(mass);
                    result = "群发消息成功";
                } else {
                    return "error:群发消息失败";
                }
                break;
            default:
                result = "error:找不到对应的素材";
        }
        return result;
    }

}
